﻿Imports System.ComponentModel
Imports System.Net.Sockets
Imports System.Net

Public Class TcpServer
    Inherits System.ComponentModel.Component

#Region "variable"
    Private Const BUFFER_SIZE As Long = 8L * 1024L '8K
    Private m_Data() As Byte = Nothing

#End Region

#Region "property"

    Private m_BufferSize As Long = BUFFER_SIZE
    <DefaultValue(GetType(Long), "8192")> _
    Public Property BufferSize() As Long
        Get
            Return m_BufferSize
        End Get
        Set(ByVal value As Long)
            m_BufferSize = value
        End Set
    End Property

    Private m_ServerSocket As Sockets.Socket
    Public Property ServerSocket() As Sockets.Socket
        Get
            Return m_ServerSocket
        End Get
        Set(ByVal value As Sockets.Socket)
            m_ServerSocket = value
        End Set
    End Property

    Private m_Active As Boolean = False
    Public Property Active() As Boolean
        Get
            Return m_Active
        End Get
        Set(ByVal value As Boolean)
            m_Active = value
        End Set
    End Property

#End Region

#Region "constructed function"

    Public Sub New()
        Me.m_Data = New Byte(BUFFER_SIZE) {}
    End Sub

    Public Sub New(ByVal socket As Sockets.Socket)
        Me.New(socket, BUFFER_SIZE)
    End Sub

    Public Sub New(ByVal socket As Sockets.Socket, ByVal bufferSize As Long)
        Me.m_ServerSocket = socket
        Me.m_BufferSize = bufferSize
        Me.m_Data = New Byte(bufferSize) {}
    End Sub

#End Region

#Region "delegate"

#End Region

#Region "events"

    ''' <summary>
    ''' 数据到达事件
    ''' </summary>
    ''' <remarks></remarks>
    Public Event DataArrivaled As DataArrivaledEventHandler
    Public Overridable Sub OnDataArrivaled(ByVal e As DataArrivaledEventArgs)
        If e IsNot Nothing Then
            RaiseEvent DataArrivaled(Me, e)
        End If
    End Sub

    ''' <summary>
    ''' 注销连接事件
    ''' </summary>
    ''' <remarks></remarks>
    Public Event DisConnect As DisConnectEventHandler
    Public Overridable Sub OnDisConnect(ByVal e As DisConnectEventArgs)
        If e IsNot Nothing Then
            RaiseEvent DisConnect(Me, e)
        End If
    End Sub
#End Region

#Region "private method"

    ''' <summary>
    ''' 接受数据
    ''' </summary>
    ''' <param name="ar"></param>
    ''' <remarks></remarks>
    Private Sub beginReceiveData(ByVal ar As IAsyncResult)
        Dim _Socket As Sockets.Socket = Nothing
        Dim _Length As Integer = 0

        _Socket = DirectCast(ar.AsyncState, Sockets.Socket)
        _Length = _Socket.EndReceive(ar)

        Me.OnDataArrivaled(New DataArrivaledEventArgs(Me.m_Data, _Socket, Nothing, False, Nothing))

        If Me.m_Active = True AndAlso _Socket.Connected Then
            _Socket.BeginReceive(Me.m_Data, 0, Me.m_Data.Length, SocketFlags.None, New AsyncCallback(AddressOf Me.beginReceiveData), _Socket)
        Else
            Me.OnDisConnect(New DisConnectEventArgs(_Socket, Nothing, False, Nothing))
        End If
    End Sub

#End Region

#Region "public method"

    Public Sub [Start]()
        Me.m_Active = True
        Me.m_ServerSocket.BeginReceive(Me.m_Data, 0, Me.m_Data.Length, SocketFlags.None, New AsyncCallback(AddressOf Me.beginReceiveData), Me.m_ServerSocket)
    End Sub

    Public Sub [Start](ByVal state As Object)
        Me.m_Active = True
        Me.m_ServerSocket = DirectCast(state, Sockets.Socket)
        Me.m_ServerSocket.BeginReceive(Me.m_Data, 0, Me.m_Data.Length, SocketFlags.None, _
                                       New AsyncCallback(AddressOf Me.beginReceiveData), Me.m_ServerSocket)
    End Sub

    Public Sub [Stop]()
        Me.m_Active = False
    End Sub

#End Region

End Class
